package cn.shujuhai.qtadmin.platform.exception;

import javax.servlet.http.HttpServletRequest;

import org.jetbrains.annotations.NotNull;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.ModelAndView;

import cn.shujuhai.qtadmin.platform.kit.CommonKit;
import cn.shujuhai.qtadmin.platform.kit.ServletUtil;
import cn.shujuhai.qtadmin.platform.pluging.result.Result;
import lombok.extern.slf4j.Slf4j;

/**
 * 版权所有:(C)1976-2018 北京清图科技有限公司
 *
 * @author: dch798
 * @日期: 2021年6月29日 下午8:19:36 @描述: [GlobalExceptionHandler]请在此简要描述类的功能
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 方法名称: exceptionHandler|描述:参数校验异常
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler({MethodArgumentNotValidException.class})
    public Object exceptionHandler(@NotNull MethodArgumentNotValidException ex, HttpServletRequest request) {
        ex.printStackTrace();
        var bindingResult = ex.getBindingResult();
        if (bindingResult.hasErrors()) {
            if (CommonKit.isJson(request)) {
                return Result.failure(bindingResult.getFieldErrors().get(0).getDefaultMessage());
            } else {
                ModelAndView modelAndView = new ModelAndView("/error");
                modelAndView.addObject("exception", ex);
                return modelAndView;
            }
        }
        return Result.failure("参数无效");
    }

    /**
     * 不 支 持 的 请 求 类 型
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    public Result handleException(HttpRequestMethodNotSupportedException e) {
        log.error(e.getMessage(), e);
        return Result.failure("不支持' " + e.getMethod() + "'请求");
    }

    /**
     * 方法名称: exceptionHandler|描述:自定义业务异常
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler({DefinitionException.class})
    public Result definitionExceptionHandler(@NotNull DefinitionException exception) {
        exception.printStackTrace();
        return Result.failure(exception.getErrorMsg());
    }

    /**
     * 权 限 异 常 处 理
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler({AccessDeniedException.class})
    public Object access(HttpServletRequest request, @NotNull AccessDeniedException e) {
        e.printStackTrace();
        if (ServletUtil.isAjax(request)) {
            return Result.failure("暂无权限");
        } else {
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.addObject("errorMessage", e.getMessage());
            modelAndView.setViewName("/error");
            return modelAndView;
        }
    }

    /**
     * 运行时异常
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler({RuntimeException.class})
    public Result runTimeExceptionHandler(@NotNull RuntimeException exception) {
        exception.printStackTrace();
        return Result.failure(exception.getMessage());
    }

    /**
     * 方法名称: exceptionHandler|描述：所有异常
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(value = Exception.class)
    public Result exceptionHandler(@NotNull Exception exception) {
        exception.printStackTrace();
        return Result.failure(exception.getMessage());
    }

    /**
     * 系统级异常及错误（Exception，Error）
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(value = Throwable.class)
    public Result throwableHandler(@NotNull Throwable throwable) {
        throwable.printStackTrace();
        return Result.failure(throwable.getMessage());
    }
}
